﻿using System;
using System.Diagnostics.Contracts;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SimpleData.Data;
using SimpleData.Data.Internals;
using SimpleData.Infrastructure.Plugins;
using SimpleData.ObjectModel;
using SimpleData.ObjectModel.Rules;
using SimpleData.ObjectModel.Internals;
using SimpleData.ObjectModel.Design;
using SimpleData.Infrastructure.Provider;

namespace SimpleData
{
	/// <summary>
	/// Contém todas as variáveis globais do sistema
	/// </summary>
	public class Runtime
	{
		private static readonly Runtime current = new Runtime();
		private RepositoryGroup repositories;// = new RepositoryGroup();
		private Plug plugins;// = new Plug();
		private IProvider<RuleName, IRuleBuilderFactory> rules;
		private IProvider<FieldTypeName, FieldTypeDescriptor> fieldTypes;

		private Runtime()
		{
			this.plugins = new Plug();
			this.repositories = new RepositoryGroup( plugins );
			
			this.rules = new RuleBuilderProvider( this.plugins );
			this.fieldTypes = new TypeDescriptorProvider( this.plugins );

			this.plugins.Connect<IProvider<RuleName, IRuleBuilderFactory>>().WithThis( this.rules );
			this.plugins.Connect<IProvider<FieldTypeName, FieldTypeDescriptor>>().WithThis( this.fieldTypes );
		}

		public static Runtime Current
		{
			get { return current; }
		}

		/// <summary>
		/// 
		/// </summary>
		public static Plug Plugins
		{
			get { return current.plugins; }
		}


		/// <summary>
		/// Obtem todas as regras do sistema
		/// </summary>
		public static IProvider<RuleName, IRuleBuilderFactory> Rules
		{
			get { return current.rules; }
		}

		/// <summary>
		/// Obtém todos os tipos utilizados no sistema
		/// </summary>
		public static IProvider<FieldTypeName, FieldTypeDescriptor> FieldTypes
		{
			get { return current.fieldTypes; }
		}

		/// <summary>
		/// 
		/// </summary>
		internal static RepositoryGroup Repositories
		{
			get { return current.repositories; }
		}

		public static string Test( string s )
		{
			Contract.Requires( !String.IsNullOrEmpty( s ), "Não pode ser empty." );

			return s + "Teste";
		}
	}
}
